package ascloud.auth.web.ctrl;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.kubernetes.client.KubernetesClientPodUtils;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.JSON;
import io.kubernetes.client.openapi.models.V1Pod;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@SecurityRequirement(name = "security_auth")
public class UserInfoController {

	@Autowired(required = false)
	private KubernetesClientPodUtils podUtils;

	@Autowired(required = false)
	private KubernetesClientUtils clientUtils;

	@Autowired(required = false)
	private LoadBalancerClient loadBalancerClient;

	@Autowired(required = false)
	private DiscoveryClient discoveryClient;

	@Autowired(required = false)
	private ReactorServiceInstanceLoadBalancer loadBalancer;

	@GetMapping("/user/info")
	@PreAuthorize("hasAuthority('SCOPE_profile')")
	public Map<String, Object> getUserInfo(@AuthenticationPrincipal Jwt principal) {
		if (null != this.podUtils) {
			V1Pod pod = this.podUtils.currentPod().get();
			String name = pod.getMetadata().getName();
			log.info("{}:{}", name, System.currentTimeMillis());
		}

		if (null != this.clientUtils) {
			ApiClient apiClient = KubernetesClientUtils.kubernetesApiClient();
			String basePath = apiClient.getBasePath();
			log.info("basePath:{}", basePath);
			JSON json = apiClient.getJSON();
			log.info("json:{}", json.toString());
		}

		if (null != this.loadBalancerClient) {
			String name = this.loadBalancerClient.getClass().getName();
			log.info("loadBalancerClientClassName:{}", name);
		}

		if (null != this.loadBalancer) {
			String name = this.loadBalancer.getClass().getName();
			log.info("loadBalancerClassName:{}", name);
		}

		if (null != this.discoveryClient) {
			String name = this.discoveryClient.getClass().getName();
			log.info("discoveryClientClassName:{}", name);

			if (this.discoveryClient instanceof CompositeDiscoveryClient compositeDiscoveryClient) {
				List<DiscoveryClient> discoveryClients = compositeDiscoveryClient.getDiscoveryClients();
				for (DiscoveryClient discoveryClient : discoveryClients) {
					log.info("discoveryClient:{}", discoveryClient.getClass().getName());
				}
			}

			int order = this.discoveryClient.getOrder();
			log.info("order:{}", order);

			List<String> services = this.discoveryClient.getServices();
			for (String service : services) {
				log.info("service:{}", service);
			}
		}

		return Collections.singletonMap("user_name_v5", principal.getClaimAsString("sub"));
	}
}